//解码控制器
module decode_cntrl(
//时钟复位
i_clk,
i_rst_n,
//解码使能
i_decode_en,
//校验结果
i_check_ok,
//解码完成和错误
o_decode_finish,
o_decode_error,
//控制信号、迭代计数器
o_decode_cnt,
o_err_cnt,
//dpram读地址
o_cn_r_addr
);

//时钟复位
input            i_clk;
input            i_rst_n;
//解码使能
input            i_decode_en;
//校验结果
input      [3:0] i_check_ok;
//解码完成和错误
output reg       o_decode_finish;
output reg       o_decode_error;
//控制信号、迭代计数器
output reg [8:0] o_decode_cnt;
output reg [5:0] o_err_cnt;
//dpram读地址
output reg [8:0] o_cn_r_addr;

//解码控制计数器
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_decode_cnt <= 9'b0;
end
else if(i_decode_en)begin
    if(o_decode_cnt == 9'd291)begin
        if(!i_check_ok)begin//传输结束
            o_decode_cnt <= o_decode_cnt;
        end
        else if(i_check_ok && o_err_cnt == 6'd50)begin
            o_decode_cnt <= o_decode_cnt;
        end
        else begin//进入迭代
            o_decode_cnt <= 9'b0;
        end
    end
    else begin
        o_decode_cnt <= o_decode_cnt + 1'b1;
    end
end
else begin
    o_decode_cnt <= 9'b0;
end

//迭代计数器
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_err_cnt <= 6'b0;
end
else if(i_decode_en)begin
    if(o_decode_cnt == 9'd291 && i_check_ok != 4'b0)begin//判断周期
        if(o_err_cnt == 6'd50)begin//迭代50次
            o_err_cnt <= o_err_cnt;
        end
        else begin
            o_err_cnt <= o_err_cnt + 1'b1;
        end
    end
    else begin
        o_err_cnt <= o_err_cnt;
    end
end
else begin
    o_err_cnt <= 6'b0;
end

//解码完成信号
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_decode_finish <= 1'b0;
end
else if(i_decode_en)begin
    if(o_decode_cnt == 9'd291 && !i_check_ok) begin
        o_decode_finish <= 1'b1;
    end
    else if(o_decode_cnt == 9'd291 && i_check_ok && o_err_cnt == 6'd50)begin
        o_decode_finish <= 1'b1;
    end  
end
else begin
    o_decode_finish <= 1'b0;
end

//错误信号
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_decode_error <= 1'b0;
end
else if(i_decode_en)begin
    if(o_decode_cnt == 9'd291 && i_check_ok != 4'b0 && o_err_cnt == 6'd50)begin//迭代20次错误
        o_decode_error <= 1'b1;
    end
    else begin
        o_decode_error <= o_decode_error;
    end
end
else begin
    o_decode_error <= 1'b0;
end

//dpram读地址
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_cn_r_addr <= 9'b0;
end
else if(i_decode_en && !o_decode_finish)begin
    if(o_decode_cnt == 9'd290)begin
        o_cn_r_addr <= 9'b0;
    end
    else begin
        o_cn_r_addr <= o_cn_r_addr + 1'b1;
    end
end
else begin
    o_cn_r_addr <= 9'b0;
end

endmodule
